package arcane.object.game.sprite;

import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import arcane.object.game.equipment.Equipment;
import arcane.object.game.map.LinkedMap;

import com.golden.gamedev.util.ImageUtil;

public class HumanoidActor extends Actor {
	/**
	 * This actor's script. Can be used to define patterns of behavior in
	 * enemies.
	 */
	private String script;
	protected ArrayList<Equipment> activeEquipment;

	// Comparator used to sort activeEquipment before rendering
	private Comparator<Equipment> renderEquipComparator;

	public HumanoidActor() {
		super();
	}

	public HumanoidActor(BufferedImage template, String path, LinkedMap map) {
		super(template, path, map);
	}

	/**
	 * Called whenever a change in activeEquipment is made, and needs to be
	 * displayed. Sorts all activeEquipment according to current specified
	 * activeEquipment comparator, and renders these to the sprite's default
	 * image.
	 */
	public void validateEquipment() {
		BufferedImage defaultImg = template.getImage();
		if (defaultImg != null) {
			BufferedImage img = ImageUtil.createImage(defaultImg.getWidth(),
					defaultImg.getHeight(), defaultImg.getTransparency());
			Graphics2D g = img.createGraphics();
			g.drawImage(defaultImg, 0, 0, null);
			Collections.sort(activeEquipment, renderEquipComparator);
			for (int i = 0; i < activeEquipment.size(); i++) {
				activeEquipment.get(i).renderOverlay(g);
			}
			g.dispose();
			setImage(img);
		}
	}

	public boolean unequip(Equipment e) {
		boolean b = activeEquipment.remove(e);
		if (b) {
			e.unequip(this);
		}
		return b;
	}

	public void equip(Equipment e) {
		if (!activeEquipment.contains(e)) {
			activeEquipment.add(e);
			e.equip(this);
		}
	}

	/**
	 * Unequips all previously equipped items, and equips the new set of
	 * equipment. Call validate equipment for this change to be reflected
	 * graphically.
	 * 
	 * @param equip
	 *            new list of equipment
	 */
	public void setEquipment(ArrayList<Equipment> equip) {
		for (int i = 0; i < activeEquipment.size(); i++) {
			activeEquipment.get(i).unequip(this);
		}
		activeEquipment = equip;
		Collections.sort(activeEquipment, renderEquipComparator);

		// Copy template
		BufferedImage temp = template.getImage();
		BufferedImage img = ImageUtil.createImage(temp.getWidth(), temp
				.getHeight(), temp.getTransparency());
		Graphics2D g = img.createGraphics();
		g.drawImage(temp, 0, 0, null);
		g.dispose();

		// render equipment overlays
		g = img.createGraphics();
		for (int i = 0; i < activeEquipment.size(); i++) {
			activeEquipment.get(i).equip(this);
			activeEquipment.get(i).renderOverlay(g);
		}
		g.dispose();
		// split images
		setImages(ImageUtil.splitImages(img, 3, 4));
	}
	
	public boolean move(int dx, int dy, int dir, long elapsedTime){
		boolean val = super.move(dx,dy,dir, elapsedTime);
		
		return val;
	}
}